﻿using ClientAPI.Network;
using System.Net.Sockets;
using System.Threading;
using System.Net;

namespace ClientAPI
{
    class NetworkController
    {
        private Socket _commandSocket;
        private Socket _chatSocket;
        private Socket _fileSocket;

        private Thread _commandListener;
        private Thread _fileListener;
       
        private Messenger _commandMessenger;

        private ReceiveFile _fileReceiver;
        private SendFile _fileSender;

        private IPAddress[] _host;

        private ChatProtocol _chat;

        public NetworkController()
        {
            _host = Dns.GetHostAddresses(Settings.Instance.GetHost());            
        }

        public void Connect()
        {
            IPEndPoint commandEnd = new IPEndPoint(_host[0], Settings.Instance.GetCommandPort());

            _commandSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _commandSocket.Connect(commandEnd);
            _commandMessenger = new Messenger(_commandSocket, "COMMAND ");

            _commandListener = new Thread(new ThreadStart(_commandMessenger.ReceiveMessage));
            _commandListener.Name = "CommandListenerTHREAD";
            _commandListener.SetApartmentState(ApartmentState.STA);
            _commandListener.Start();
        }

        public bool IsConnected()
        {
            return _commandSocket.Connected;
        }

        public void ChatConnect(ChatProtocol chat)
        {
            _chat = chat;
            IPEndPoint chatEnd = new IPEndPoint(_host[0], Settings.Instance.GetChatPort());

            _chatSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _chatSocket.Connect(chatEnd);

            _chat.ChatConnect(_chatSocket, CommandProtocol.Instance.GetUserName());
        }

        public void SendFileConnect(string filePath, string fileDescription)
        {
            IPEndPoint fileEnd = new IPEndPoint(_host[0], Settings.Instance.GetFilePort());
            _fileSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _fileSocket.Connect(fileEnd);
            _fileSender = new SendFile(filePath, fileDescription, _fileSocket);

            _fileListener = new Thread(new ThreadStart(_fileSender.Send));
            _fileListener.Name = "FileReceiveTHREAD";

            _fileListener.SetApartmentState(ApartmentState.STA);
            _fileListener.Start();
        }

        public void ReceiveFileConnect(string fileName)
        {
            IPEndPoint fileEnd = new IPEndPoint(_host[0], Settings.Instance.GetFilePort());
            _fileSocket = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            _fileSocket.Connect(fileEnd);
            _fileReceiver = new ReceiveFile(fileName, _fileSocket);

            _fileListener = new Thread(new ThreadStart(_fileReceiver.Receive));
            _fileListener.Name = "FileSendTHREAD";

            _fileListener.SetApartmentState(ApartmentState.STA);
            _fileListener.Start();
        }

        public void SendCommandMessage(string message)
        {
            _commandMessenger.SendMessage(message);
        }

        public void Disconnect()
        {
            if (_chatSocket != null)
            {
                if (_chatSocket.Connected)
                {
                    _chatSocket.Disconnect(true);
                    _chatSocket.Close();
                }
            }

            _commandListener.Abort();
            _commandSocket.Disconnect(true);
            _commandSocket.Close();
        }

        public void DisconnectChatHandler()
        {
            if (_chat != null)
                _chat.Disconnect();
        }

    }
}
